package sunyu.controller.shiro;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import sunyu.controller.common.CommonController;
import sunyu.controller.shiro.tools.ResourceTools;
import sunyu.kit.common.LogKit;
import sunyu.kit.common.StringKit;
import sunyu.mapper.shiro.pojo.Role;
import sunyu.service.shiro.ResourceService;
import sunyu.service.shiro.RoleService;

import javax.annotation.Resource;
import java.util.*;

/**
 * 角色管理控制器
 *
 * @author 孙宇
 */
@Controller
@RequestMapping("/shiro/role")
public class RoleController extends CommonController {

    private static final Logger logger = LogKit.getLogger();

    @Resource(name = "roleService")
    private RoleService roleService;

    @Resource(name = "resourceService")
    private ResourceService resourceService;

    /**
     * 表单name前缀绑定
     * <p>
     * 表单提交需要role.xxx
     *
     * @param binder
     */
    @InitBinder("role")
    public void initBinderResource(WebDataBinder binder) {
        binder.setFieldDefaultPrefix("role.");
    }

    /**
     * 跳转到列表页面
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:role:list"})
    public String list(Model model) {
        return "/shiro/role/list";
    }

    /**
     * 获得角色信息
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:role:list"})
    @ResponseBody
    public Map<String, Object> list(@RequestBody Map<String, Object> params) {
        Map<String, Object> p = new HashMap<>();
        Page page = new Page();
        if (params.get("pageNum") != null) {
            page.setPageNum(Integer.parseInt(params.get("pageNum").toString()));
        }
        if (params.get("pageSize") != null) {
            page.setPageSize(Integer.parseInt(params.get("pageSize").toString()));
        }
        if (params.get("sort") != null) {
            page.setOrderBy(params.get("sort") + " " + params.get("order"));
        }
        List<Role> roles = roleService.select(page, null);

        PageInfo pageInfo = new PageInfo(roles);

        p.put("total", pageInfo.getTotal());
        p.put("rows", pageInfo.getList());

        return p;
    }

    /**
     * 跳转到新增页面
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/insert", method = RequestMethod.GET)
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:role:insert"})
    public String insert(Model model) {
        return insertPage(model);
    }

    /**
     * 跳转到insert页面
     *
     * @param model
     * @return
     */
    private String insertPage(Model model) {
        model.addAttribute("action", "insert");//告诉前台页面的form，准备调用insert操作

        ResourceTools.getResourceTree(model, resourceService);

        return "/shiro/role/form";
    }

    /**
     * 新增
     *
     * @param role
     * @param resourceIds
     * @param model
     * @return
     */
    @RequestMapping(value = "/insert", method = RequestMethod.POST)
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:role:insert"})
    public String insert(@ModelAttribute("role") Role role,
                         String resourceIds,
                         Model model) {
        Map<String, Object> params = new HashMap<String, Object>() {{
            put("name", role.getName());
        }};
        if (roleService.count(params) > 0) {
            model.addAttribute("errMsg", "角色名称已存在！");
            return insertPage(model);
        }

        role.setId(UUID.randomUUID().toString());
        role.setCreated(new Date());
        role.setModified(role.getCreated());

        roleService.insert(role, resourceIds);

        return "redirect:/shiro/role/list";
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/delete/{id}")
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:role:delete"})
    public String delete(@PathVariable("id") String id) {
        roleService.delete(id);
        return "redirect:/shiro/role/list";
    }

    /**
     * 跳转到修改页面
     *
     * @param model
     * @param id
     * @return
     */
    @RequestMapping(value = "/update/{id}", method = RequestMethod.GET)
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:role:update"})
    public String update(Model model,
                         @PathVariable("id") String id) {
        Role role = roleService.selectById(id);
        return updatePage(model, role);
    }

    private String updatePage(Model model,
                              Role role) {
        model.addAttribute("role", role);

        model.addAttribute("action", "update");//告诉前台页面的form，准备调用update操作

        ResourceTools.getResourceTree(model, resourceService);

        String resourceIds = roleService.getResourceIds(role.getId());//当前角色拥有的资源，多个资源逗号分隔
        if (StringKit.isNotBlank(resourceIds)) {
            model.addAttribute("resourceIds", resourceIds);
        }

        return "/shiro/role/form";
    }

    /**
     * 修改
     *
     * @param role
     * @param resourceIds
     * @param model
     * @return
     */
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @RequiresAuthentication
    @RequiresPermissions(value = {"shiro:role:update"})
    public String update(@ModelAttribute("role") Role role,
                         String resourceIds,
                         Model model) {

        Map<String, Object> params = new HashMap<String, Object>() {{
            put("name", role.getName());
        }};
        List<Role> roles = roleService.select(null, params);
        if (roles != null && roles.size() > 0) {
            for (Role r : roles) {
                if (!r.getId().equals(role.getId())) {//说明角色名称已经有人占用了
                    model.addAttribute("errMsg", "角色名称已经存在！");
                    return updatePage(model, role);
                }
            }
        }

        role.setModified(new Date());
        roleService.update(role, resourceIds);

        return "redirect:/shiro/role/list";
    }

}
